﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpBolt.Input;
using OpenTK;
using OpenTK.Input;
using SharpBolt.Basics;

namespace TestGame.InputUtilites
{
    class OpenTKInputProvider : IInputProvider
    {

        Dictionary<OpenTK.Input.Key,string> keysAlias;
        Dictionary<OpenTK.Input.MouseButton, string> mouseButtonsAlias;
        Dictionary<OpenTK.Input.JoystickButton, string> joystickButtonsAlias;

        InputObserver.KeyEvent keyDown;
        InputObserver.KeyEvent keyUp;

        public OpenTKInputProvider()
        {
            keysAlias = new Dictionary<OpenTK.Input.Key, string>();
            keysAlias[OpenTK.Input.Key.W] = "up";
            keysAlias[OpenTK.Input.Key.S] = "down";
            keysAlias[OpenTK.Input.Key.D] = "right";
            keysAlias[OpenTK.Input.Key.A] = "left";
            keysAlias[OpenTK.Input.Key.Enter] = "start";
            keysAlias[OpenTK.Input.Key.Space] = "jump";
            keysAlias[OpenTK.Input.Key.Escape] = "back";

            mouseButtonsAlias = new Dictionary<MouseButton, string>();
            mouseButtonsAlias[MouseButton.Left] = "grab";

            joystickButtonsAlias = new Dictionary<JoystickButton, string>();

            Manipulators = new Dictionary<string, bManipulator>();
        }

        public void  AttachToKeyboard(KeyboardDevice keyboard){
            keyboard.KeyDown += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(window_KeyDown);
            keyboard.KeyUp += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(window_KeyUp);
        }

        public void AttachToMouse(MouseDevice mouse)
        {
            mouse.Move += new EventHandler<MouseMoveEventArgs>(mouse_Move);
            mouse.ButtonDown += new EventHandler<MouseButtonEventArgs>(mouse_ButtonDown);
            mouse.ButtonUp += new EventHandler<MouseButtonEventArgs>(mouse_ButtonUp);
        }

        void mouse_ButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (keyUp == null) return;
            if (!mouseButtonsAlias.ContainsKey(e.Button)) return;
            keyUp(mouseButtonsAlias[e.Button]);
        }

        void mouse_ButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (keyDown == null) return;
            if (!mouseButtonsAlias.ContainsKey(e.Button)) return;
            keyDown(mouseButtonsAlias[e.Button]);
        }

        void mouse_Move(object sender, MouseMoveEventArgs e)
        {
            if(!Manipulators.ContainsKey("pointer"))
                Manipulators["pointer"] = new bManipulator();

            Manipulators["pointer"].Position = new InductBase.Vec2(e.Position.X, e.Position.Y);
        }

        void window_KeyUp(object sender, OpenTK.Input.KeyboardKeyEventArgs e)
        {
            if (keyUp == null) return;
            if (!keysAlias.ContainsKey(e.Key)) return;

            keyUp(keysAlias[e.Key]);
            
        }

        void window_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs e)
        {
            if (keyDown == null) return;
            if (!keysAlias.ContainsKey(e.Key)) return;

            keyDown(keysAlias[e.Key]);
        }

        event InputObserver.KeyEvent IInputProvider.KeyDown
        {
            add { keyDown += value; }
            remove { keyDown -= value; }
        }

        event InputObserver.KeyEvent IInputProvider.KeyUp
        {
            add { keyUp += value; }
            remove { keyUp += value; }
        }


        string[] IInputProvider.GetKnownKeys()
        {
            List<string> result = new List<string>();
            result.AddRange(keysAlias.Values);
            result.AddRange(mouseButtonsAlias.Values);
            result.AddRange(joystickButtonsAlias.Values);
            return result.ToArray();
        }

        Dictionary<string, bManipulator> Manipulators;

        public Dictionary<string, SharpBolt.Basics.bManipulator> GetManipulators()
        {
            return Manipulators;
        }
    }
}
